#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
squash-vault CLI 入口模块

版本: 0.1.0
"""

import os
import subprocess
import click
from pathlib import Path
from loguru import logger
import importlib.resources as pkg_resources


def generate_launcher_c(entry_path: str) -> str:
    """读取 launcher.c.in 模板并替换入口路径"""
    c_code = pkg_resources.read_text('squash_vault', 'launcher.c.in')
    return c_code.replace("{entry_path}", entry_path)


def run_cmd(cmd: str, desc: str) -> None:
    """执行 shell 命令并记录日志"""
    logger.info(f"[执行] {desc}: {cmd}")
    result = subprocess.run(cmd, shell=True)
    if result.returncode != 0:
        logger.error(f"[错误] {desc} 失败，返回码: {result.returncode}")
        raise RuntimeError(f"命令执行失败: {cmd}")
    logger.success(f"[完成] {desc}")


@click.command()
@click.option(
    '--image-name',
    required=True,
    type=str,
    help='Docker 镜像名称，如 myimg:latest'
)
@click.option(
    '--squashfuse-path',
    required=True,
    type=click.Path(exists=True),
    help='squashfuse 可执行文件路径'
)
@click.option(
    '--output-dir',
    required=True,
    type=click.Path(),
    help='输出文件目录路径'
)
@click.option(
    '--binary-name',
    required=True,
    type=str,
    help='生成的二进制文件名'
)
@click.option(
    '--entry-path',
    required=True,
    type=str,
    help='容器内执行路径，如 /usr/bin/python3 -m splitbarcode'
)
def main(image_name, squashfuse_path, output_dir, binary_name, entry_path):
    """
    将 Docker 镜像和 squashfuse 可执行文件打包为 all-in-one 启动器
    """
    work_dir = Path(output_dir)
    work_dir.mkdir(parents=True, exist_ok=True)

    rootfs_dir = work_dir / "rootfs"
    sqfs_file = work_dir / "rootfs.sqfs"
    squashfuse_o = work_dir / "squashfuse.o"
    sqfs_h = work_dir / "rootfs.sqfs.h"
    launcher_c = work_dir / "launcher.c"
    binary_file = work_dir / binary_name
    rootfs_tar = work_dir / "rootfs.tar"

    # 0. 导出 docker 镜像为 rootfs.tar
    docker_flag = work_dir / "docker.done"
    if not docker_flag.exists():
        docker_cmd = f"docker run --rm {image_name} tar -C / --exclude=./proc --exclude=./sys --exclude=./dev --exclude=./tmp -cf - . > {rootfs_tar}"
        run_cmd(docker_cmd, "导出 docker 镜像为 rootfs.tar")
        docker_flag.write_text("ok")
    else:
        logger.info("[跳过] 已存在 docker 镜像导出标志")

    # 1. 解压 rootfs.tar
    untar_flag = work_dir / "untar.done"
    if not untar_flag.exists():
        run_cmd(f"mkdir -p {rootfs_dir}", "创建 rootfs 目录")
        run_cmd(f"tar -xf {rootfs_tar} -C {rootfs_dir}", "解压 rootfs.tar")
        untar_flag.write_text("ok")
    else:
        logger.info("[跳过] 已存在 rootfs 解压标志")

    # 2. 制作 squashfs 镜像
    squashfs_flag = work_dir / "squashfs.done"
    if not squashfs_flag.exists():
        run_cmd(f"mksquashfs {rootfs_dir} {sqfs_file} -comp xz -noappend", "制作 squashfs 镜像")
        squashfs_flag.write_text("ok")
    else:
        logger.info("[跳过] 已存在 squashfs 镜像标志")

    # 3. 直接拷贝 squashfuse 到输出目录
    squashfuse_flag = work_dir / "squashfuse.done"
    if not squashfuse_flag.exists():
        squashfuse_bin = work_dir / "squashfuse"
        run_cmd(f"cp {squashfuse_path} {squashfuse_bin}", "拷贝 squashfuse 可执行文件")
        squashfuse_flag.write_text("ok")
    else:
        logger.info("[跳过] 已存在 squashfuse 拷贝标志")

    # 4. 生成 rootfs.sqfs.h
    sqfs_h_flag = work_dir / "sqfs_h.done"
    if not sqfs_h_flag.exists():
        logger.info(f"[执行] 生成 rootfs.sqfs.h: xxd -i {sqfs_file} > {sqfs_h}")
        with open(sqfs_h, "w") as hfile:
            result = subprocess.run(f"xxd -i {sqfs_file}", shell=True, stdout=hfile)
            if result.returncode != 0:
                logger.error(f"[错误] 生成 rootfs.sqfs.h 失败，返回码: {result.returncode}")
                raise RuntimeError("xxd 命令执行失败")
        logger.success(f"[完成] 生成 rootfs.sqfs.h")
        sqfs_h_flag.write_text("ok")
    else:
        logger.info("[跳过] 已存在 rootfs.sqfs.h 标志")

    # 5. 生成 launcher.c
    launcher_c_flag = work_dir / "launcher_c.done"
    if not launcher_c_flag.exists():
        logger.info(f"[执行] 生成 launcher.c 文件")
        with open(launcher_c, "w") as f:
            f.write(generate_launcher_c(entry_path))
        logger.success(f"[完成] 生成 launcher.c 文件")
        launcher_c_flag.write_text("ok")
    else:
        logger.info("[跳过] 已存在 launcher.c 标志")

    # 6. 编译、strip
    binary_flag = work_dir / "binary.done"
    if not binary_flag.exists():
        print(f"[编译] gcc -o {binary_file} {launcher_c} -O2")
        subprocess.run([
            "gcc", "-o", str(binary_file), str(launcher_c), "-O2"
        ], check=True)
        run_cmd(f"strip {binary_file}", "strip 二进制文件")
        run_cmd(f"chmod +x {binary_file}", "设置执行权限")
        binary_flag.write_text("ok")
    else:
        logger.info("[跳过] 已存在最终二进制标志")

    logger.success(f"[完成] 生成全部文件: {binary_file}")


if __name__ == "__main__":
    main()